/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package proy1sistdistribuidos.modelo;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import java.util.logging.Level;
import java.util.logging.Logger;
import proy1sistdistribuidos.control.advertisements.AdvertisementImagenImpl;
import proy1sistdistribuidos.control.advertisements.AdvertisementRecurso;

/**
 *
 * @author Carlos DIaz Maya, Juan Felipe Garcia
 */
public class ControladorExclusion implements Observer {
    public static final int puertoSocketes = 8081;
    private ControladorPermisoExclusion cont;

    public ControladorExclusion() {
        cont = new ControladorPermisoExclusion();
    }

    public void adicionarObservador(Observer o){
        this.getCont().addObserver(o);
    }

    public void eliminarObservador(Observer o){
        this.getCont().deleteObserver(o);
    }

    public void update(Observable o, Object arg) {
        if (arg instanceof ArrayList) {
           List<NodoRemoto> recs = null;
           try{
            if(arg != null){
                recs = null;
                List listprb = (List) arg;
                Iterator elIt = listprb.iterator();
                while(elIt.hasNext()){
                    Object obu = elIt.next();
                    if(obu instanceof AdvertisementImagenImpl){
                        recs = null;
                        break;
                    } else if(obu instanceof NodoRemoto) {
                        recs = (List<NodoRemoto>) listprb;
                        break;
                    }
                }
            }
          } catch(Exception f){
              recs = null;
          }

            if (recs != null) {
                try {
                    //TODO publicar estado
                    boolean tengoPermiso = true;
                    for (NodoRemoto rec : recs) {
                        try {
                            String ip = rec.getDireccionIP();
                            Socket elSockete = new Socket(ip, puertoSocketes);
                            String comando = "SolicitarPermiso";
                            PrintWriter pregunta = new PrintWriter(elSockete.getOutputStream(), true);
                            BufferedReader respuesta = new BufferedReader(new InputStreamReader(elSockete.getInputStream()));
                            //Se envia el comando al nodo
                            pregunta.println(comando);
                            //Se recibe la respuesta del nodo
                            String respNodo = respuesta.readLine();
                            if (respNodo != null && !respNodo.equals("")) {
                                tengoPermiso = tengoPermiso && Boolean.parseBoolean(respNodo);
                            }
                            elSockete.close();
                        } catch (UnknownHostException ex) {
                            ex.printStackTrace();
                        } catch (IOException ex) {
                            ex.printStackTrace();
                        }
                    }
                    EstadoGeneral estadoGeneral = ControladorEstado.obtenerInstancia().getEstadoLocalDescarga();
                    estadoGeneral.setNombreEstado(estadoGeneral.RECIBIR_PERMISO);
                    estadoGeneral.setMensaje(String.valueOf(tengoPermiso));
                    ControladorEstado.obtenerInstancia().actualizarEstadoGeneralInicial(estadoGeneral);
                    this.getCont().notificarPermiso(tengoPermiso);
                } catch (Exception ex) {
                    Logger.getLogger(ControladorExclusion.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }

    /**
     * @return the cont
     */
    public ControladorPermisoExclusion getCont() {
        return cont;
    }

    /**
     * @param cont the cont to set
     */
    public void setCont(ControladorPermisoExclusion cont) {
        this.cont = cont;
    }

}
